home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
System Booster
/
System Booster.iso
/
Texteditors
/
Mg1b
/
Source
/
region.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-26
|
7KB
|
287 lines
/*
* Region based commands.
* The routines in this file
* deal with the region, that magic space
* between "." and mark. Some functions are
* commands. Some functions are just for
* internal use.
*/
#include "def.h"
/*
* Kill the region. Ask "getregion"
* to figure out the bounds of the region.
* Move "." to the start, and kill the characters.
*/
/*ARGSUSED*/
killregion(f, n, k) {
register int s;
REGION region;
if ((s=getregion(®ion)) != TRUE)
return (s);
if ((lastflag&CFKILL) == 0) /* This is a kill type */
kdelete(); /* command, so do magic */
thisflag |= CFKILL; /* kill buffer stuff. */
curwp->w_dotp = region.r_linep;
curwp->w_doto = region.r_offset;
return (ldelete(region.r_size, KFORW));
}
/*
* Copy all of the characters in the
* region to the kill buffer. Don't move dot
* at all. This is a bit like a kill region followed
* by a yank.
*/
/*ARGSUSED*/
copyregion(f, n, k) {
register LINE *linep;
register int loffs;
register int s;
REGION region;
if ((s=getregion(®ion)) != TRUE)
return (s);
if ((lastflag&CFKILL) == 0) /* Kill type command. */
kdelete();
thisflag |= CFKILL;
linep = region.r_linep; /* Current line. */
loffs = region.r_offset; /* Current offset. */
while (region.r_size--) {
if (loffs == llength(linep)) { /* End of line. */
if ((s=kinsert('\n', KFORW)) != TRUE)
return (s);
linep = lforw(linep);
loffs = 0;
} else { /* Middle of line. */
if ((s=kinsert(lgetc(linep, loffs), KFORW)) != TRUE)
return (s);
++loffs;
}
}
return (TRUE);
}
/*
* Lower case region. Zap all of the upper
* case characters in the region to lower case. Use
* the region code to set the limits. Scan the buffer,
* doing the changes. Call "lchange" to ensure that
* redisplay is done in all buffers.
*/
/*ARGSUSED*/
lowerregion(f, n, k) {
register LINE *linep;
register int loffs;
register int c;
register int s;
REGION region;
if ((s=getregion(®ion)) != TRUE)
return (s);
lchange(WFHARD);
linep = region.r_linep;
loffs = region.r_offset;
while (region.r_size--) {
if (loffs == llength(linep)) {
linep = lforw(linep);
loffs = 0;
} else {
c = lgetc(linep, loffs);
if (ISUPPER(c) != FALSE)
lputc(linep, loffs, TOLOWER(c));
++loffs;
}
}
return (TRUE);
}
/*
* Upper case region. Zap all of the lower
* case characters in the region to upper case. Use
* the region code to set the limits. Scan the buffer,
* doing the changes. Call "lchange" to ensure that
* redisplay is done in all buffers.
*/
/*ARGSUSED*/
upperregion(f, n, k) {
register LINE *linep;
register int loffs;
register int c;
register int s;
REGION region;
if ((s=getregion(®ion)) != TRUE)
return (s);
lchange(WFHARD);
linep = region.r_linep;
loffs = region.r_offset;
while (region.r_size--) {
if (loffs == llength(linep)) {
linep = lforw(linep);
loffs = 0;
} else {
c = lgetc(linep, loffs);
if (ISLOWER(c) != FALSE)
lputc(linep, loffs, TOUPPER(c));
++loffs;
}
}
return (TRUE);
}
/*
* This routine figures out the bound of the region
* in the current window, and stores the results into the fields
* of the REGION structure. Dot and mark are usually close together,
* but I don't know the order, so I scan outward from dot, in both
* directions, looking for mark. The size is kept in a long. At the
* end, after the size is figured out, it is assigned to the size
* field of the region structure. If this assignment loses any bits,
* then we print an error. This is "type independent" overflow
* checking. All of the callers of this routine should be ready to
* get an ABORT status, because I might add a "if regions is big,
* ask before clobberring" flag.
*/
getregion(rp) register REGION *rp; {
register LINE *flp;
register LINE *blp;
register long fsize; /* Long now. */
register long bsize;
if (curwp->w_markp == NULL) {
ewprintf("No mark set in this window");
return (FALSE);
}
if (curwp->w_dotp == curwp->w_markp) { /* "r_size" always ok. */
rp->r_linep = curwp->w_dotp;
if (curwp->w_doto < curwp->w_marko) {
rp->r_offset = curwp->w_doto;
rp->r_size = (RSIZE) (curwp->w_marko-curwp->w_doto);
} else {
rp->r_offset = curwp->w_marko;
rp->r_size = (RSIZE) (curwp->w_doto-curwp->w_marko);
}
return (TRUE);
}
blp = curwp->w_dotp; /* Get region size. */
flp = curwp->w_dotp;
bsize = curwp->w_doto;
fsize = llength(flp)-curwp->w_doto+1;
while (flp!=curbp->b_linep || lback(blp)!=curbp->b_linep) {
if (flp != curbp->b_linep) {
flp = lforw(flp);
if (flp == curwp->w_markp) {
rp->r_linep = curwp->w_dotp;
rp->r_offset = curwp->w_doto;
return (setsize(rp,
(RSIZE) (fsize+curwp->w_marko)));
}
fsize += llength(flp)+1;
}
if (lback(blp) != curbp->b_linep) {
blp = lback(blp);
bsize += llength(blp)+1;
if (blp == curwp->w_markp) {
rp->r_linep = blp;
rp->r_offset = curwp->w_marko;
return (setsize(rp,
(RSIZE) (bsize-curwp->w_marko)));
}
}
}
ewprintf("Bug: lost mark"); /* Gak! */
return (FALSE);
}
/*
* Set size, and check for overflow.
*/
setsize(rp, size) register REGION *rp; register RSIZE size; {
rp->r_size = size;
if (rp->r_size != size) {
ewprintf("Region is too large");
return (FALSE);
}
return (TRUE);
}
#ifdef PREFIXREGION
/*
* Implements one of my favorite keyboard macros; put a string at the
* beginning of a number of lines in a buffer. The quote string is
* settable by using set-prefix-string. Great for quoting mail, which
* is the real reason I wrote it, but also has uses for creating bar
* comments (like the one you're reading) in C code.
*/
#define PREFIXLENGTH 40
static char prefix_string[PREFIXLENGTH] = { '>', '\0' };
/*
* Prefix the region with whatever is in prefix_string.
* Leaves dot at the beginning of the line after the end
* of the region. If an argument is given, prompts for the
* line prefix string.
*/
/*ARGSUSED*/
prefixregion(f, n, k)
{
register int s;
register LINE *first, *last;
register int nline;
REGION region;
char *prefix = prefix_string;
if ((f == TRUE) && ((s = setprefix(FALSE, 1, KRANDOM)) != TRUE))
return (s);
/* get # of lines to affect */
if ((s = getregion(®ion)) != TRUE)
return (s);
first = region.r_linep;
last = (first == curwp->w_dotp) ? curwp->w_markp : curwp->w_dotp;
for (nline = 1; first != last; nline++)
first = lforw(first);
/*move to beginning of region */
curwp->w_dotp = region.r_linep;
curwp->w_doto = region.r_offset;
/* for each line, go to beginning and insert the prefix string */
while (nline--) {
gotobol();
for (prefix = prefix_string; *prefix; prefix++)
(VOID) linsert((RSIZE) 1, *prefix);
forwline(FALSE, 1, KRANDOM);
}
gotobol();
return (TRUE);
}
/*
* Set prefix string.
*/
/*ARGSUSED*/
setprefix(f, n, k)
{
char buf[PREFIXLENGTH];
register int s;
if (prefix_string[0] == '\0')
s = ereply("Prefix string: ",buf,sizeof buf);
else
s = ereply("Prefix string (default %s): ",
buf,sizeof buf,prefix_string);
if (s == TRUE)
(VOID) strcpy(prefix_string, buf);
if ((s == FALSE) && (prefix_string[0] != '\0')) /* CR -- use old one */
s = TRUE;
return (s);
}
#endif